package mathsys2;

/**
 * 习题集系统类：《面向对象软件构造》4.6节需求
 * 核心：Main入口实现50道加法/减法/混合习题生成、显示与校验
 */
public class ExerciseSystem {
    private static final int EXERCISE_COUNT = 50; // 实验固定50道/类型
    private static final int PER_LINE = 5; // 每行显示5道（《模块化软件构造》故事二）

    public static void main(String[] args) {
        System.out.println("======================================");
        System.out.println("    100以内加减法习题生成系统（实验版）");
        System.out.println("======================================\n");

        try {
            // -------------------------- 1. 生成并显示50道加法习题 --------------------------
            System.out.println("【1/3】生成50道加法习题...");
            ExerciseSet additionSet = new ExerciseSet(EXERCISE_COUNT, false);
            additionSet.generateAdditions();
            // 校验加法习题（无重复、结果合规）
            validateExerciseSet(additionSet, "加法");
            // 格式化显示（每行5道）
            additionSet.printExercises(PER_LINE);

            // -------------------------- 2. 生成并显示50道减法习题 --------------------------
            System.out.println("\n【2/3】生成50道减法习题...");
            ExerciseSet subtractionSet = new ExerciseSet(EXERCISE_COUNT, false);
            subtractionSet.generateSubtractions();
            // 校验减法习题
            validateExerciseSet(subtractionSet, "减法");
            // 格式化显示
            subtractionSet.printExercises(PER_LINE);

            // -------------------------- 3. 生成并显示50道混合习题 --------------------------
            System.out.println("\n【3/3】生成50道混合习题（加法25道+减法25道）...");
            ExerciseSet mixedSet = new ExerciseSet(EXERCISE_COUNT, true);
            mixedSet.generateMixedExercises();
            // 校验混合习题（额外校验比例）
            validateMixedExerciseSet(mixedSet);
            // 格式化显示
            mixedSet.printExercises(PER_LINE);

            // -------------------------- 4. 实验完成提示 --------------------------
            System.out.println("\n======================================");
            System.out.println("    实验需求全部完成！");
            System.out.println("    ✅ 50道加法+50道减法+50道混合习题生成成功；");
            System.out.println("    ✅ 所有习题无重复，结果符合100以内约束；");
            System.out.println("    ✅ 按每行5道格式化显示完成。");
            System.out.println("======================================");

        } catch (IllegalArgumentException | IllegalStateException e) {
            System.err.println("\n❌ 系统异常：" + e.getMessage());
            System.err.println("🔍 请检查运算约束或生成逻辑，确保符合实验要求！");
        }
    }

    // 校验单一类型习题集（加法/减法）
    private static void validateExerciseSet(ExerciseSet set, String type) {
        if (set.getGeneratedCount() != EXERCISE_COUNT) {
            throw new IllegalStateException(type + "习题数量错误：" + set.getGeneratedCount() + "道（目标50道）");
        }
        if (set.hasDuplicate()) {
            throw new IllegalStateException(type + "习题存在重复，违反实验约束！");
        }
        if (!set.isResultValid()) {
            throw new IllegalStateException(type + "习题存在结果违规（加法超100/减法为负）！");
        }
        System.out.println("✅ " + type + "习题校验通过：50道无重复，结果合规！");
    }

    // 校验混合习题集（额外校验加法:减法=1:1）
    private static void validateMixedExerciseSet(ExerciseSet mixedSet) {
        // 基础校验（数量、重复、结果）
        validateExerciseSet(mixedSet, "混合");
        // 比例校验（25道±1误差）
        long addCount = mixedSet.getExercises().stream().filter(a -> a.getOperator() == '+').count();
        long subCount = EXERCISE_COUNT - addCount;
        if (addCount < 24 || addCount > 26) {
            throw new IllegalStateException("混合习题比例失衡：加法" + addCount + "道，减法" + subCount + "道（预期各25道）");
        }
        System.out.println("✅ 混合习题比例校验通过：加法" + addCount + "道，减法" + subCount + "道！");
    }
}